package com.shrct.businessprocess.project.impl;

import com.shrct.businessprocess.common.CurrencyType;
import com.shrct.businessprocess.money.Moneys;
import com.shrct.businessprocess.project.RCCustomerContract;
import com.shrct.businessprocess.project.RCCustomerContractMoneyAccept;
import com.shrct.businessprocess.project.RCCustomerContractMoneyAcceptAssignment;
import com.shrct.businessprocess.project.RCExchangeRate;
import com.shrct.businessprocess.project.RCProject;
import com.shrct.businessprocess.project.RCRealMoney;
import com.shrct.businessprocess.project.impl.RCCustomerContractImpl;
import com.shrct.businessprocess.project.impl.RCCustomerContractMoneyAcceptAssignmentImpl;
import com.shrct.businessprocess.project.proxy.RCCustomerContractMoneyAcceptProxy;
import edu.fudan.mylang.pf.BaseModelObject;
import edu.fudan.mylang.pf.IObjectFactory;
import java.util.Collection;
import java.util.Date;
import javax.persistence.AssociationOverride;
import javax.persistence.AssociationOverrides;
import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.eclipse.xtext.xbase.lib.DoubleExtensions;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.ObjectExtensions;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.hibernate.annotations.DiscriminatorOptions;

@Entity
@DiscriminatorValue("RCCUSTOMERCONTRACTMONEYACCEPT_TYPE")
@DiscriminatorOptions(force = true)
@DiscriminatorColumn(length = 64)
@Table(name = "rccustomercontractmoneyaccept")
public class RCCustomerContractMoneyAcceptImpl extends BaseModelObject implements RCCustomerContractMoneyAccept {
  public RCCustomerContractMoneyAcceptImpl() {
    super();
  }
  
  public RCCustomerContractMoneyAcceptImpl(final RCCustomerContract contract) {
    super();
    this.contract = contract;
  }
  
  @JoinColumn(name = "contract_id")
  @ManyToOne(targetEntity = RCCustomerContractImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST })
  private RCCustomerContract contract;
  
  public RCCustomerContract getContract() {
    return this.contract;
  }
  
  public RCCustomerContractMoneyAccept setContract(final RCCustomerContract contract) {
    this.contract = contract;
    return this;			
    
  }
  
  private Date acceptDate;
  
  public Date getAcceptDate() {
    return this.acceptDate;
  }
  
  public RCCustomerContractMoneyAccept setAcceptDate(final Date acceptDate) {
    this.acceptDate = acceptDate;
    return this;			
    
  }
  
  @Embedded
  @AttributeOverrides(value = { @AttributeOverride(name = "amount", column = @Column(name = "acceptMoney_amount") ), @AttributeOverride(name = "exchangeRate", column = @Column(name = "acceptMoney_exchangeRate") ), @AttributeOverride(name = "workaround", column = @Column(name = "acceptMoney_workaround") ) } )
  @AssociationOverrides(value = @AssociationOverride(name = "currencyType", joinColumns = @JoinColumn(name = "acceptMoney_currencyType") ) )
  private RCRealMoney acceptMoney = com.shrct.businessprocess.project.RCRealMoney.create();
  
  public RCRealMoney getAcceptMoney() {
    return this.acceptMoney;
  }
  
  public RCCustomerContractMoneyAccept setAcceptMoney(final RCRealMoney acceptMoney) {
    this.acceptMoney = acceptMoney;
    return this;			
    
  }
  
  private String comment;
  
  public String getComment() {
    return this.comment;
  }
  
  public RCCustomerContractMoneyAccept setComment(final String comment) {
    this.comment = comment;
    return this;			
    
  }
  
  private Boolean assignFinished = Boolean.valueOf(false);
  
  public Boolean getAssignFinished() {
    return this.assignFinished;
  }
  
  public RCCustomerContractMoneyAccept setAssignFinished(final Boolean assignFinished) {
    this.assignFinished = assignFinished;
    return this;			
    
  }
  
  @OneToMany(targetEntity = RCCustomerContractMoneyAcceptAssignmentImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE }, mappedBy = "accept")
  private Collection<RCCustomerContractMoneyAcceptAssignment> assignments = new java.util.ArrayList<com.shrct.businessprocess.project.RCCustomerContractMoneyAcceptAssignment>();;
  
  public Collection<RCCustomerContractMoneyAcceptAssignment> getAssignments() {
    return this.assignments;
  }
  
  public RCCustomerContractMoneyAcceptAssignment createAndAddtoAssignments() {
    getAssignments().size();
    com.shrct.businessprocess.project.RCCustomerContractMoneyAcceptAssignment rCCustomerContractMoneyAcceptAssignment = new com.shrct.businessprocess.project.impl.RCCustomerContractMoneyAcceptAssignmentImpl(this);
    getObjectFactory().create(rCCustomerContractMoneyAcceptAssignment);
    getAssignments().add(rCCustomerContractMoneyAcceptAssignment);
    return rCCustomerContractMoneyAcceptAssignment;
    
  }
  
  public RCCustomerContractMoneyAcceptAssignment createAndAddtoAssignments(final Procedure1<RCCustomerContractMoneyAcceptAssignment> updater) {
    getAssignments().size();
    com.shrct.businessprocess.project.RCCustomerContractMoneyAcceptAssignment rCCustomerContractMoneyAcceptAssignment = new com.shrct.businessprocess.project.impl.RCCustomerContractMoneyAcceptAssignmentImpl(this);
    getObjectFactory().create(rCCustomerContractMoneyAcceptAssignment);
    getAssignments().add(rCCustomerContractMoneyAcceptAssignment);
    return rCCustomerContractMoneyAcceptAssignment;
    
  }
  
  public RCCustomerContractMoneyAccept removeAllAssignments() {
    for(RCCustomerContractMoneyAcceptAssignment obj : this.assignments){
    	getObjectFactory().delete(obj);
    }
    this.assignments.clear();
    return this;	
    
  }
  
  public RCCustomerContractMoneyAccept removeFromAssignments(final RCCustomerContractMoneyAcceptAssignment rCCustomerContractMoneyAcceptAssignment) {
    this.assignments.remove(rCCustomerContractMoneyAcceptAssignment);
    getObjectFactory().delete(rCCustomerContractMoneyAcceptAssignment);
    return this;
    
  }
  
  public void monyAssigned() {
    RCRealMoney _remainMoney = this.getRemainMoney();
    Double _amount = _remainMoney.getAmount();
    boolean _greaterThan = ((_amount).doubleValue() > 0);
    if (_greaterThan) {
      this.assignFinished = Boolean.valueOf(false);
    } else {
      this.assignFinished = Boolean.valueOf(true);
    }
  }
  
  public RCRealMoney getTotalAssignedMoney() {
    final Function1<RCCustomerContractMoneyAcceptAssignment,RCRealMoney> _function = new Function1<RCCustomerContractMoneyAcceptAssignment,RCRealMoney>() {
        public RCRealMoney apply(final RCCustomerContractMoneyAcceptAssignment it) {
          RCRealMoney _amount = it.getAmount();
          return _amount;
        }
      };
    Iterable<RCRealMoney> _map = IterableExtensions.<RCCustomerContractMoneyAcceptAssignment, RCRealMoney>map(this.assignments, _function);
    RCProject _project = this.contract.getProject();
    RCExchangeRate _defaultExchangeRate = _project.getDefaultExchangeRate();
    RCRealMoney _sumRealMoney = Moneys.sumRealMoney(_map, _defaultExchangeRate);
    return _sumRealMoney;
  }
  
  public RCRealMoney getRemainMoney() {
    RCRealMoney _rCRealMoney = new RCRealMoney();
    final Procedure1<RCRealMoney> _function = new Procedure1<RCRealMoney>() {
        public void apply(final RCRealMoney it) {
          Double _amount = RCCustomerContractMoneyAcceptImpl.this.acceptMoney.getAmount();
          RCRealMoney _totalAssignedMoney = RCCustomerContractMoneyAcceptImpl.this.getTotalAssignedMoney();
          Double _amount_1 = _totalAssignedMoney.getAmount();
          double _minus = DoubleExtensions.operator_minus(_amount, _amount_1);
          it.setAmount(Double.valueOf(_minus));
          Double _exchangeRate = RCCustomerContractMoneyAcceptImpl.this.acceptMoney.getExchangeRate();
          it.setExchangeRate(_exchangeRate);
          CurrencyType _currencyType = RCCustomerContractMoneyAcceptImpl.this.acceptMoney.getCurrencyType();
          it.setCurrencyType(_currencyType);
        }
      };
    RCRealMoney _doubleArrow = ObjectExtensions.<RCRealMoney>operator_doubleArrow(_rCRealMoney, _function);
    return _doubleArrow;
  }
  
  public static RCCustomerContractMoneyAccept create(final RCCustomerContract contract, final IObjectFactory objectFactory) {
    com.shrct.businessprocess.project.RCCustomerContractMoneyAccept rCCustomerContractMoneyAccept = new com.shrct.businessprocess.project.impl.RCCustomerContractMoneyAcceptImpl(
    	contract
    );
    objectFactory.create(rCCustomerContractMoneyAccept);
    return rCCustomerContractMoneyAccept;			
    
  }
  
  public static RCCustomerContractMoneyAccept createRCCustomerContractMoneyAcceptImpl(final RCCustomerContract contract, final IObjectFactory objectFactory, final Procedure1<RCCustomerContractMoneyAccept> init) {
    com.shrct.businessprocess.project.RCCustomerContractMoneyAccept rCCustomerContractMoneyAccept = new com.shrct.businessprocess.project.impl.RCCustomerContractMoneyAcceptImpl(
    	contract
    );
    objectFactory.create(rCCustomerContractMoneyAccept);
    init.apply(rCCustomerContractMoneyAccept);
    
    return rCCustomerContractMoneyAccept;			
    
  }
  
  public RCCustomerContractMoneyAcceptProxy toProxy() {
    com.shrct.businessprocess.project.proxy.RCCustomerContractMoneyAcceptProxy proxy = new com.shrct.businessprocess.project.proxy.RCCustomerContractMoneyAcceptProxy();
    proxy.setId(this.getId());
    if(this instanceof edu.fudan.mylang.pf.INamedModelObject){
    	proxy.setName(((edu.fudan.mylang.pf.INamedModelObject)this).getEntityName());
    }
    return proxy;
    
  }
}
